package io.wongxd.solution.compose.custom

import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import io.wongxd.solution.compose.composeTheme.AppThemeHolder
import io.wongxd.solution.compose.composeTheme.textStyle
import io.wongxd.solution.compose.composeTheme.white
import kotlinx.coroutines.launch

@Composable
fun <T> WPickerColumn(
    list: List<T>,
    itemHeight: Dp,
    itemWidth: Dp? = null,
    valueState: MutableState<T>,
    renderItem: @Composable (item: T, selected: Boolean) -> Unit
) {
    val pickerCoroutineScope = rememberCoroutineScope()
    val listState = rememberLazyListState()
    var value by valueState

    LazyColumn(
        state = listState,
        modifier = Modifier.height(itemHeight * 3)
    ) {
        item {
            Surface(Modifier.height(itemHeight)) {}
        }

        itemsIndexed(items = list, key = { index, item -> item.hashCode() }) { index, item ->

            val widthModifier = itemWidth?.let { Modifier.width(itemWidth) } ?: Modifier
            Box(
                modifier = Modifier
                    .height(itemHeight)
                    .then(widthModifier)
                    .clickable {
                        pickerCoroutineScope.launch {
                            listState.animateScrollToItem(index = index)
                        }
                    }
                    .padding(start = 5.dp, end = 5.dp), Alignment.Center
            ) {
                renderItem(item, listState.firstVisibleItemIndex == index)
            }
        }

        item {
            Surface(Modifier.height(itemHeight)) {}
        }

    }

    /**
     * Jetpack Compose LazyColumn的滑动开始、结束及进行中事件
     * 参考文章 https://blog.csdn.net/asd912756674/article/details/122544808
     */
    if (listState.isScrollInProgress) {

        LaunchedEffect(Unit) {
            //只会调用一次，相当于滚动开始
        }
        //当state处于滚动时，preScrollStartOffset会被初始化并记忆,不会再被更改
        val preScrollStartOffset by remember { mutableStateOf(listState.firstVisibleItemScrollOffset) }
        val preItemIndex by remember { mutableStateOf(listState.firstVisibleItemIndex) }
        val isScrollDown = if (listState.firstVisibleItemIndex > preItemIndex) {
            //第一个可见item的index大于开始滚动时第一个可见item的index，说明往下滚动了
            true
        } else if (listState.firstVisibleItemIndex < preItemIndex) {
            //第一个可见item的index小于开始滚动时第一个可见item的index，说明往上滚动了
            false
        } else {
            //第一个可见item的index等于开始滚动时第一个可见item的index,对比item offset
            listState.firstVisibleItemScrollOffset > preScrollStartOffset
        }

        DisposableEffect(Unit) {
            onDispose {
                //	滑动结束时给状态赋值，并自动对齐
                value = list[listState.firstVisibleItemIndex]
                pickerCoroutineScope.launch {
                    listState.animateScrollToItem(listState.firstVisibleItemIndex)
                }
            }
        }
    }

    //  选择初始值
    LaunchedEffect(Unit) {

        var initIndex = 0

        for (index in list.indices) {
            if (value == list[index]) {
                initIndex = index
                break
            }
        }
        pickerCoroutineScope.launch {
            listState.animateScrollToItem(initIndex)
        }
    }
}

@Preview(showBackground = true)
@Composable
private fun PickerPreview() {
    val s = remember {
        mutableStateOf(0)
    }

    WPickerColumn(
        list = (1..60).toList(),
        itemHeight = 60.dp,
        itemWidth = 80.dp,
        valueState = s
    ) { item, selected ->

        Box(
            Modifier
                .height(60.dp)
                .width(80.dp)
                .background(if (selected) Color.Green else Color.Red),
            contentAlignment = Alignment.Center
        ) {
            Text(text = "$item", style = AppThemeHolder.textStyle.sp14.white())
        }
    }

}